package audiobeatz;

import java.awt.EventQueue;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;

import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;

import audio.ABPlayer;
import audio.SABFileFilter;
import audio.SABFileManager;
import audio.SInstrument;
import audio.WavePlayer;
import audiobeatz.TMetronome.EOffBeats;

import chords.EChord;
import chords.EInstrument;
import chords.KeyChordMapping;
import chords.TimedChord;

import java.awt.event.KeyEvent;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import java.awt.Color;
import javax.swing.border.BevelBorder;
import javax.swing.SwingConstants;
import javax.swing.JLayeredPane;
import javax.swing.border.LineBorder;

import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.JRadioButtonMenuItem;

public class AudioBeatz extends JFrame implements KeyEventDispatcher, Observer {

    private static final long serialVersionUID = 5217515508355059596L;

    private JPanel contentPane;

    private JButton btnRecord;
    private JButton btnPlay;

    private JLabel lblNewLabel;

    private boolean isRecording = false;
    private boolean isPaused = false;

    private Vector<TimedChord> recordedData = new Vector<>();
    private long startOfRecording = 0;
    private long pauseStartTime = 0;
    private long totalPauseTime = 0;

    private ABPlayer player;

    private JButton btnStop;
    private JButton btnSet;
    private JButton btnPause;

    private KeyChordMapping keysChords;

    ArrayList<JButton> buttons = new ArrayList<JButton>();

    private TMetronome metronome;

    private static JSlider slider;

    private Color keyPressedColor = Color.ORANGE;

    public static void setSlider(int num) {
	slider.setValue(num);
    }

    /**
     * Main method, entry point
     */
    public static void main(String[] args) {
	EventQueue.invokeLater(new Runnable() {
	    @Override
	    public void run() {
		try {
		    AudioBeatz ab = new AudioBeatz();
		    ab.setVisible(true);
		} catch (Exception e) {
		    e.printStackTrace();
		}
	    }
	});
    }

    /**
     * Create all the GUI stuff
     */
    public AudioBeatz() {
	super("AudioBeatz");

	setResizable(false);
	setSize(new Dimension(1037, 478));
	setLocation(100, 250);
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	// Create the metronome and set it to no-OffBeats and OFF, but start it
	// so it's ready
	metronome = new TMetronome(60, EOffBeats.OFF);
	metronome.addObserver(this);
	new Thread(metronome).start();

	player = new ABPlayer(new Vector<TimedChord>(), this);

	// Add ourselves to the keyboard manager to get all keyboard input
	// events (not just when the JFrame is in focus)
	KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);

	keysChords = new KeyChordMapping();

	// Create the menu bar
	JMenuBar menuBar = new JMenuBar();
	setJMenuBar(menuBar);

	JMenu mnFile = new JMenu("File");
	menuBar.add(mnFile);

	JMenu mnOptions = new JMenu("Options");
	menuBar.add(mnOptions);

	JMenu mnHelp = new JMenu("Help");
	menuBar.add(mnHelp);

	JMenuItem helpMenuItem = new JMenuItem("User Guide");
	helpMenuItem.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		Icon ic = new ImageIcon("gfx/userguide.jpg");
		JOptionPane.showMessageDialog(AudioBeatz.this, "Click the metronome (at least twice) to find BPM", "User Guide", JOptionPane.INFORMATION_MESSAGE, ic);
	    }
	});
	mnHelp.add(helpMenuItem);

	JMenu mnInstrument = new JMenu("Instrument");
	mnOptions.add(mnInstrument);

	ButtonGroup buttonGroupI = new ButtonGroup();

	JRadioButtonMenuItem rdbtnmnInstNewRadioItem = new JRadioButtonMenuItem("Piano");
	rdbtnmnInstNewRadioItem.setSelected(true);
	rdbtnmnInstNewRadioItem.addChangeListener(new ChangeListener() {
	    @Override
	    public void stateChanged(ChangeEvent arg0) {
		SInstrument.setInstrument(EInstrument.Piano);
	    }
	});
	mnInstrument.add(rdbtnmnInstNewRadioItem);
	buttonGroupI.add(rdbtnmnInstNewRadioItem);

	JSeparator separator_2 = new JSeparator();
	mnInstrument.add(separator_2);

	JRadioButtonMenuItem rdbtnmnInstNewRadioItem_1 = new JRadioButtonMenuItem("Organ");
	rdbtnmnInstNewRadioItem_1.addChangeListener(new ChangeListener() {
	    @Override
	    public void stateChanged(ChangeEvent e) {
		SInstrument.setInstrument(EInstrument.Organ);
	    }
	});
	mnInstrument.add(rdbtnmnInstNewRadioItem_1);
	buttonGroupI.add(rdbtnmnInstNewRadioItem_1);

	JRadioButtonMenuItem rdbtnmnInstNewRadioItem_2 = new JRadioButtonMenuItem("Steel Drums");
	rdbtnmnInstNewRadioItem_2.addChangeListener(new ChangeListener() {
	    @Override
	    public void stateChanged(ChangeEvent e) {
		SInstrument.setInstrument(EInstrument.SteelDrum);
	    }
	});
	mnInstrument.add(rdbtnmnInstNewRadioItem_2);
	buttonGroupI.add(rdbtnmnInstNewRadioItem_2);

	JMenu mnMetronome = new JMenu("Metronome");
	mnOptions.add(mnMetronome);

	// make sure the radio buttons can't all be selected, but only 1 at a
	// time
	ButtonGroup buttonGroupM = new ButtonGroup();

	JMenu mnNewMenu = new JMenu("Set Off-Beat");
	mnMetronome.add(mnNewMenu);

	JRadioButtonMenuItem radioButtonMenuItem = new JRadioButtonMenuItem("Every 3rd");
	radioButtonMenuItem.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent arg0) {
		metronome.setOffBeats(EOffBeats.Three);
	    }
	});
	mnNewMenu.add(radioButtonMenuItem);
	buttonGroupM.add(radioButtonMenuItem);

	JRadioButtonMenuItem radioButtonMenuItem_1 = new JRadioButtonMenuItem("Every 4th");
	radioButtonMenuItem_1.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		metronome.setOffBeats(EOffBeats.Four);
	    }
	});
	mnNewMenu.add(radioButtonMenuItem_1);
	buttonGroupM.add(radioButtonMenuItem_1);

	JSeparator separator = new JSeparator();
	mnNewMenu.add(separator);

	JRadioButtonMenuItem radioButtonMenuItem_2 = new JRadioButtonMenuItem("Disabled");
	radioButtonMenuItem_2.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		metronome.setOffBeats(EOffBeats.OFF);
	    }
	});
	radioButtonMenuItem_2.setSelected(true);
	mnNewMenu.add(radioButtonMenuItem_2);
	buttonGroupM.add(radioButtonMenuItem_2);

	JMenuItem mntmEnterBpm = new JMenuItem("Enter BPM...");
	mntmEnterBpm.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		while (true) {
		    try {
			int bpm = Integer.parseInt(JOptionPane.showInputDialog("Please enter BPM [0-480]:"));
			if (bpm < 0) {
			    JOptionPane.showMessageDialog(AudioBeatz.this, "No negative numbers allowed");
			    return;
			} else if (bpm > 480) {
			    JOptionPane.showMessageDialog(AudioBeatz.this, "Max allowed value is 480");
			    return;
			}
			metronome.setBPM(bpm);
			return;
		    } catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(AudioBeatz.this, "BPM not set. You may only use numbers between [0-9] as input.");
			e.printStackTrace();
		    }
		}
	    }
	});
	mnMetronome.add(mntmEnterBpm);

	JMenuItem mntmExit = new JMenuItem("Exit");
	mntmExit.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent e) {
		System.exit(0);
	    }
	});

	JSeparator separator_1 = new JSeparator();
	mnFile.add(separator_1);

	JMenuItem mntmLoadRecording = new JMenuItem("Load Recording...");
	mntmLoadRecording.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent e) {
		if (isRecording) {
		    JOptionPane.showMessageDialog(AudioBeatz.this, "You cannot load a file while recording!");
		    return;
		}
		JFileChooser fc = new JFileChooser("storage");
		fc.setFileFilter(new SABFileFilter("AudioBeatzFileFormat", "abf"));
		KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(AudioBeatz.this);
		if (fc.showOpenDialog(AudioBeatz.this) == JFileChooser.APPROVE_OPTION) {
		    try {
			recordedData = SABFileManager.loadFile(fc.getSelectedFile());
			btnPlay.setEnabled(true);
			JOptionPane.showMessageDialog(AudioBeatz.this, "File loaded succesfully!");
		    } catch (FileNotFoundException e1) {
			JOptionPane.showMessageDialog(AudioBeatz.this, "File not found!");
		    } catch (ClassNotFoundException e1) {
			JOptionPane.showMessageDialog(AudioBeatz.this, "Class not found: " + e1.getMessage());
		    } catch (IOException e1) {
			JOptionPane.showMessageDialog(AudioBeatz.this, "IOException: " + e1.getMessage());
		    }
		}
		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(AudioBeatz.this);
	    }
	});
	mnFile.add(mntmLoadRecording);

	JMenuItem mntmSaveRecording = new JMenuItem("Save Recording...");
	mntmSaveRecording.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		JFileChooser fc = new JFileChooser("storage");
		fc.setFileFilter(new SABFileFilter("AudioBeatzFileFormat", "abf"));
		KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(AudioBeatz.this);
		if (fc.showSaveDialog(AudioBeatz.this) == JFileChooser.APPROVE_OPTION) {
		    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(AudioBeatz.this);
		    try {
			if (recordedData.size() == 0) {
			    JOptionPane.showMessageDialog(AudioBeatz.this, "No data recorded.");
			    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(AudioBeatz.this);
			    return;
			}
			SABFileManager.saveFile(fc.getSelectedFile(), recordedData);
		    } catch (IOException e) {
			JOptionPane.showMessageDialog(AudioBeatz.this, "Could not save file: " + e.getMessage());
			KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(AudioBeatz.this);
			return;
		    }
		    JOptionPane.showMessageDialog(AudioBeatz.this, "File saved succesfully!");
		}
		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(AudioBeatz.this);
	    }
	});
	mnFile.add(mntmSaveRecording);
	mnFile.add(mntmExit);

	// For some reason it's good practice to add a panel to the contentpane
	// and never directly place objects other than 1 panel on the content
	// pane.
	// I'm not sure why. Maybe it's easier to change the program, if objects
	// are not on the top-most panel.
	contentPane = new JPanel();
	contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
	setContentPane(contentPane);
	contentPane.setLayout(new BorderLayout(0, 0));

	// Create the main panel for the whole application
	JPanel panel = new JPanel();
	contentPane.add(panel, BorderLayout.CENTER);
	panel.setLayout(null);
	panel.setBackground(Color.WHITE);

	// Add a record button with an actionlistener, and begin recording when
	// pressed.
	btnRecord = new JButton("Record");
	btnRecord.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		if (btnRecord.getText().equals("Record")) {
		    recordedData = new Vector<TimedChord>();
		    recordedData.add(new TimedChord(0, EChord.Silence, SInstrument.getInstrument()));
		    btnRecord.setText("Stop Recording!");
		    btnPlay.setEnabled(false);
		    btnPause.setEnabled(true);
		    isRecording = true;
		    startOfRecording = System.currentTimeMillis();
		} else {
		    btnPause.setEnabled(false);
		    unPauseAll();
		    isRecording = false;
		    btnPlay.setEnabled(true);
		    btnRecord.setText("Record");
		}
	    }
	});
	btnRecord.setFocusable(false);
	btnRecord.setBounds(10, 11, 127, 35);
	panel.add(btnRecord);

	// A play button with an actionlistener to start playing the recorded
	// data when pressed.
	// Initially set disabled. This is changed upon recording for the first
	// time.
	btnPlay = new JButton("Play Recording");
	btnPlay.setBounds(147, 11, 118, 35);
	panel.add(btnPlay);
	btnPlay.setIgnoreRepaint(true);
	btnPlay.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
	btnPlay.setEnabled(false);
	btnPlay.setFocusable(false);
	btnPlay.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent e) {
		if (btnPlay.getText().equals("Play Recording")) {
		    btnPlay.setText("Stop Playback");
		    btnRecord.setEnabled(false);
		    player = new ABPlayer(recordedData, AudioBeatz.this);
		    player.start();
		    btnPause.setEnabled(true);
		} else {
		    btnPause.setEnabled(false);
		    unPauseAll();
		    btnPlay.setText("Play Recording");
		    btnRecord.setEnabled(true);
		    player.askToStop();
		}
	    }
	});

	JPanel panel_1 = new JPanel();
	panel_1.setBackground(Color.BLACK);
	panel_1.setBounds(10, 64, 639, 347);
	panel.add(panel_1);
	panel_1.setLayout(null);

	JLayeredPane layeredPane = new JLayeredPane();
	layeredPane.setOpaque(true);
	layeredPane.setBackground(new Color(153, 217, 234));
	layeredPane.setBounds(50, 50, 533, 243);
	panel_1.add(layeredPane);
	layeredPane.setLayout(null);

	JButton button_17 = new JButton("", new ImageIcon("metronome/metro.gif"));
	button_17.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		metronome.addClickBeat();
	    }
	});
	button_17.setFocusable(false);
	button_17.setBounds(659, 11, 281, 400);
	panel.add(button_17);

	// Metronome start button, does the obvious
	btnSet = new JButton("Start");
	btnSet.setFocusable(false);
	btnSet.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		try {
		    metronome.setBPM(Integer.parseInt(lblNewLabel.getText()));
		    metronome.startMetro();
		    btnStop.setEnabled(true);
		    btnSet.setEnabled(false);
		} catch (NumberFormatException e) {
		    JOptionPane.showMessageDialog(AudioBeatz.this, "Only numbers [0-9] are allowed.");
		    return;
		}
	    }
	});
	btnSet.setBounds(475, 17, 80, 23);
	panel.add(btnSet);

	slider = new JSlider(SwingConstants.VERTICAL, 0, 480, 90);
	slider.setFocusable(false);
	slider.addChangeListener(new ChangeListener() {
	    @Override
	    public void stateChanged(ChangeEvent e) {
		metronome.setBPM(((JSlider) e.getSource()).getValue());
		lblNewLabel.setText("" + ((JSlider) e.getSource()).getValue());
	    }
	});
	slider.setPaintLabels(true);
	slider.setSnapToTicks(true);
	slider.setPaintTicks(true);
	slider.setMinorTickSpacing(1);
	slider.setMajorTickSpacing(30);
	slider.setBounds(950, 11, 59, 400);
	panel.add(slider);

	// Metronome stop button
	btnStop = new JButton("Stop");
	btnStop.setEnabled(false);
	btnStop.setFocusable(false);
	btnStop.addActionListener(new ActionListener() {
	    @Override
	    public void actionPerformed(ActionEvent arg0) {
		metronome.stopMetro();
		btnStop.setEnabled(false);
		btnSet.setEnabled(true);
	    }
	});
	btnStop.setBounds(565, 17, 80, 23);
	panel.add(btnStop);

	// Create 2 labels, 1 for the static displayed stuff, and one for the
	// changing BPM counter
	lblNewLabel = new JLabel("90");
	lblNewLabel.setHorizontalAlignment(SwingConstants.RIGHT);
	lblNewLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
	lblNewLabel.setBounds(399, 22, 26, 14);
	panel.add(lblNewLabel);

	JLabel lblNewLabel_1 = new JLabel("BPM");
	lblNewLabel_1.setBounds(435, 22, 36, 14);
	panel.add(lblNewLabel_1);

	btnPause = new JButton("Pause");
	btnPause.setEnabled(false);
	btnPause.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {
		if (btnPause.getText().equals("Pause")) {
		    pauseAll();
		    pauseStartTime = System.currentTimeMillis();
		} else {
		    totalPauseTime += System.currentTimeMillis() - pauseStartTime;
		    unPauseAll();
		}
	    }
	});
	btnPause.setBounds(277, 11, 117, 35);
	panel.add(btnPause);

	// -- Create the buttons that correspond to piano-keys
	// White keys
	JButton button_5 = new JButton("C");
	button_5.setBounds(6, 6, 50, 230);

	JButton button_4 = new JButton("D");
	button_4.setBounds(53, 6, 50, 230);

	JButton button_1 = new JButton("E");
	button_1.setBounds(100, 6, 50, 230);

	JButton button = new JButton("F");
	button.setBounds(147, 6, 50, 230);

	JButton button_8 = new JButton("G");
	button_8.setBounds(194, 6, 50, 230);

	JButton button_9 = new JButton("A");
	button_9.setBounds(241, 6, 50, 230);

	JButton button_14 = new JButton("B");
	button_14.setBounds(288, 6, 50, 230);

	JButton button_13 = new JButton("C1");
	button_13.setBounds(335, 6, 50, 230);

	JButton button_12 = new JButton("D1");
	button_12.setBounds(382, 6, 50, 230);

	JButton button_15 = new JButton("E1");
	button_15.setBounds(429, 6, 50, 230);

	JButton button_18 = new JButton("F1");
	button_18.setBounds(476, 6, 50, 230);

	// Black keys
	JButton button_2 = new JButton("C#");
	button_2.setBounds(38, 6, 31, 135);

	JButton button_3 = new JButton("D#");
	button_3.setBounds(85, 6, 31, 135);

	JButton button_6 = new JButton("F#");
	button_6.setBounds(179, 6, 31, 135);

	JButton button_7 = new JButton("G#");
	button_7.setBounds(226, 6, 31, 135);

	JButton button_10 = new JButton("Bb");
	button_10.setBounds(273, 6, 31, 135);

	JButton button_11 = new JButton("C#1");
	button_11.setBounds(367, 6, 31, 135);

	JButton button_16 = new JButton("D#1");
	button_16.setBounds(415, 6, 31, 135);

	// Add all the lastKeyPressed to an Array so we can change the settings
	// easily
	buttons.add(button);
	buttons.add(button_1);
	buttons.add(button_2);
	buttons.add(button_3);
	buttons.add(button_4);
	buttons.add(button_5);
	buttons.add(button_6);
	buttons.add(button_7);
	buttons.add(button_8);
	buttons.add(button_9);
	buttons.add(button_10);
	buttons.add(button_11);
	buttons.add(button_12);
	buttons.add(button_13);
	buttons.add(button_14);
	buttons.add(button_15);
	buttons.add(button_16);
	buttons.add(button_18);

	for (JButton b : buttons) {
	    b.setBorder(new LineBorder(new Color(0, 0, 0), 3));
	    b.setVerticalTextPosition(SwingConstants.BOTTOM);
	    b.setVerticalAlignment(SwingConstants.BOTTOM);
	    b.setIgnoreRepaint(true);
	    b.setFocusable(false);
	    b.addMouseListener(new ButtonListener(b, this));

	    // black keys got different settings than the whites, so do a check
	    // for which we're working with
	    if (b.getText().contains("#") || b.getText().contains("Bb")) {
		b.setForeground(Color.LIGHT_GRAY);
		b.setBackground(Color.BLACK);
		layeredPane.add(b, JLayeredPane.MODAL_LAYER);
	    } else {
		b.setBackground(Color.WHITE);
		layeredPane.add(b);
	    }
	}
    }

    protected void pauseAll() {
	isPaused = true;
	player.askToPause();
	btnPause.setText("Resume");
    }

    protected void unPauseAll() {
	isPaused = false;
	player.askToResume();
	btnPause.setText("Pause");
    }

    // handle when a user presses a keyboard key
    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
	if (e.getID() == KeyEvent.KEY_PRESSED) {
	    EChord chord = keysChords.getChord(e.getExtendedKeyCode());
	    if (chord != null) {
		// Check if key is ready (to avoid key-repeats)
		if (chord.isReady()) {
		    // make the corresponding button on the screen look as
		    // if pressed
		    for (JButton b : buttons) {
			if (chord.getFilename().equals(b.getText())) {
			    // register it as pressed. this will make it stay
			    // not-ready until a keyReleased event is
			    // registered, see the handler for KEY_RELEASED
			    // below
			    chord.setReady(false);
			    b.setBackground(keyPressedColor);
			    // play it
			    new WavePlayer(SInstrument.getInstrument().getFolder() + File.separator + SInstrument.getInstrument().getFilename() + chord.getFilename() + ".wav").start();

			    // Store it as recorded data, but only if we're
			    // recording
			    if (isRecording && !isPaused)
				addTimedChord(chord.getFilename());
			    break;
			}
		    }
		}
	    }
	} else if (e.getID() == KeyEvent.KEY_RELEASED) {
	    EChord chord = keysChords.getChord(e.getExtendedKeyCode());
	    if (chord != null) {
		for (JButton b : buttons) {
		    if (chord.getFilename().equals(b.getText())) {
			chord.setReady(true);
			if (chord.getFilename().contains("Bb") || chord.getFilename().contains("#"))
			    b.setBackground(Color.BLACK);
			else
			    b.setBackground(Color.WHITE);
			break;
		    }
		}
	    }
	}
	return false;
    }

    @Override
    // called when the metronome changed state, see the metronome class
    public void update(Observable arg0, Object arg1) {
	if (arg0 == metronome) {
	    lblNewLabel.setText("" + metronome.getBPM());
	    btnStop.setEnabled(metronome.isRunning());
	}
    }

    public boolean isRecording() {
	return this.isRecording;
    }

    public boolean isPaused() {
	return this.isPaused;
    }

    public void addTimedChord(String chord) {
	for (EChord c : EChord.values()) {
	    if (c.getFilename().equals(chord)) {
		recordedData.add(new TimedChord(System.currentTimeMillis() - startOfRecording - totalPauseTime, c, SInstrument.getInstrument()));
		break;
	    }
	}
    }

    public void playerFinished() {
	showReleasedChord();
	btnPlay.setText("Play Recording");
	btnRecord.setEnabled(true);
	player.askToStop();
	btnPause.setEnabled(false);
    }

    public void showReleasedChord() {
	for (JButton b : buttons) {
	    if (b.getText().contains("Bb") || b.getText().contains("#"))
		b.setBackground(Color.BLACK);
	    else
		b.setBackground(Color.WHITE);
	}
    }

    public void showPressedChord(EChord chord) {
	for (JButton b : buttons) {
	    if (b.getText().equals(chord.getFilename())) {
		b.setBackground(keyPressedColor);
		break;
	    }
	}
    }
}